﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DNASequencing.core.data
{
    class Node
    {
        /// <summary>
        /// List of oligonucleotides.
        /// </summary>
        protected List<AOligonucleotide> _lSequences;

        /// <summary>
        /// List of oligonucleotides.
        /// </summary>
        public List<AOligonucleotide> oligonucleotides
        {
            get
            {
                return _lSequences;
            }
        }

        /// <summary>
        /// Table of the followers of the current node. It should have
        /// four elements.
        /// </summary>
        protected Node[] _nNext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aacid"></param>
        /// <returns></returns>
        public Node this[char aacid]
        {
            get
            {
                switch (aacid)
                {
                    case 'A':
                        return _nNext[0];
                    case 'C':
                        return _nNext[1];
                    case 'G':
                        return _nNext[2];
                    case 'T':
                        return _nNext[3];
                    default:
                        throw new InvalidCastException();
                }
            }
            set
            {
                switch (aacid)
                {
                    case 'A':
                        _nNext[0] = value;
                        break;
                    case 'C':
                        _nNext[1] = value;
                        break;
                    case 'G':
                        _nNext[2] = value;
                        break;
                    case 'T':
                        _nNext[3] = value;
                        break;
                    default:
                        throw new InvalidCastException();
                }
            }
        }

        /// <summary>
        /// Creates new Node object. Sets <code>_nNext</code> to be 4-elements table.
        /// </summary>
        public Node()
        {
            _nNext = new Node[4];
            _lSequences = new List<AOligonucleotide>();
        }

        /// <summary>
        /// Root only method. Adds oligonucleotide throught whole three. Root does not 
        /// remember the sequence.
        /// </summary>
        /// <param name="sequence"></param>
        public void add(AOligonucleotide sequence)
        {
            add(sequence, -1);
        }

        /// <summary>
        /// Not-root method. Adds oligonucleotide to the node's oligonucleotides list and sends
        /// the oligonucleotide to the follower described by the index-th value of oligonucleotide.
        /// </summary>
        /// <param name="sequence">Adding oligonucleotide.</param>
        /// <param name="index">Current index of the oligonucleotide, which determinates which follower we send to.</param>
        public void add(AOligonucleotide sequence, int index)
        {
            if (index >= 0)
                _lSequences.Add(sequence);

            if (++index < sequence.getSequence().Length)
            {
                Node temp = this[sequence.getSequence()[index]];
                if (temp == null)
                {
                    temp = new Node();
                }
                temp.add(sequence, index);
                this[sequence.getSequence()[index]] = temp;
            }
        }
    }
}
